package com.tsinghua.server.riskmodel.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tsinghua.server.common.Result;
import com.tsinghua.server.common.exception.BusinessException;
import com.tsinghua.server.common.utils.BaseUtil;
import com.tsinghua.server.index.entity.FxjcQuota;
import com.tsinghua.server.index.service.FxjcQuotaService;
import com.tsinghua.server.original.mapper.FxjcCyzMapper;
import com.tsinghua.server.riskmodel.entity.Assessment;
import com.tsinghua.server.riskmodel.entity.FxjcModelTraningList;
import com.tsinghua.server.riskmodel.service.FxjcModelTraningListService;
import com.tsinghua.server.train.entity.FxjcZqBase;
import com.tsinghua.server.train.entity.PyVo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

/**
 * @description:
 * @author: Mr.Eric
 * @create: 2022/3/5 17:01
 */
@RestController
@RequestMapping(value = "/module/")
public class ModuleTrainController {

    @Resource
    private FxjcCyzMapper fxjcCyzMapper;
    @Resource
    private FxjcModelTraningListService modelTraningListService;
    @Resource
    private FxjcQuotaService fxjcQuotaService;

    /**
     * 模型训练
     * @return
     */
    @GetMapping(value = "train/list")
    public Result list(@RequestParam(name = "pageSize", defaultValue = "10", required = false) Integer pageSize,
                       @RequestParam(name = "pageNo", defaultValue = "1", required = false) Integer pageNo,
                       @RequestParam(name = "type", required = false) Integer type,
                       @RequestParam(name = "zwzt", required = false) String zwzt) {
        Map<String, Object> params = new HashMap<>();

        String tableName = "";
        switch (type) {
            case 1: tableName ="fxjc_ctz_traning_result"; break;
            case 2: tableName ="fxjc_cyz_traning_result"; break;
            case 3: tableName ="fxjc_yh_traning_result"; break;
            case 4: tableName ="fxjc_bx_traning_result"; break;
            case 5: tableName ="fxjc_zq_traning_result"; break;
        }

        List<Map<String,Object>> tableData =  fxjcCyzMapper.selectByTable(tableName);

        Map<String,Object> map = new HashMap<>();
        map.put("pageSize", pageSize);
        map.put("pageNo",(pageNo-1)*pageSize);
        map.put("tableName",tableName);
        Page page = new Page(pageNo,pageSize);
        IPage dataList =  fxjcCyzMapper.selectDataByTable(page,tableName,zwzt);

        params.put("tableData",tableData);
        params.put("dataList",dataList);
        return Result.succ(params);
    }


    /**
     * 模型评估
     *
     * @return
     */
    @GetMapping(value = "assessment/list")
    public Result AssessmentList() {
        List<Assessment> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Assessment assessment = new Assessment();
            assessment.setModelName("model" + i);
            assessment.setPrecision("80%");
            assessment.setRecall("60%");
            assessment.setF1("39%");
            list.add(assessment);
        }
        return Result.succ(list);
    }


    /**
     * 运行
     * @return
     */
    @GetMapping(value = "process/list")
    public Result processlList() {
        Map<String, Object> params = new HashMap<>();
        for (int i= 0;i<1000;i++) {
            params.put("no", 1+i);
            params.put("zqdm", "00001");
            params.put("fxzt", "00001");
            params.put("sfwy", "1");
        }
        return Result.succ(params);
    }


    /**
     * 模型训练
     * @return
     */
    @GetMapping(value = "training-log")
    public Result trainLog(@RequestParam(name = "type", required = false) Integer type) throws IOException, InterruptedException {

        if (type == 1) {
            if (checkTraning("ctz_best_model")){
				checkTraningBefore(type);
                FxjcModelTraningList fxjcModelTraningList = new FxjcModelTraningList();
                fxjcModelTraningList.setMoudleName("ctz_best_model");
                fxjcModelTraningList.setXlDate(new Date());
                fxjcModelTraningList.setType(type);
                modelTraningListService.save(fxjcModelTraningList);
                return BaseUtil.execPyScript(new PyVo("城投债",2,"ctz_best_model"));
                // 验证
            }else {
                FxjcModelTraningList fxjcModelTraning = checkTraningObj("ctz_basic_model");
                // 数据库列表 无basic_model
                if (fxjcModelTraning == null) {
                    FxjcModelTraningList fxjcModelTraningList = new FxjcModelTraningList();
                    fxjcModelTraningList.setMoudleName("ctz_basic_model");
                    fxjcModelTraningList.setXlDate(new Date());
                    fxjcModelTraningList.setType(type);
                    modelTraningListService.save(fxjcModelTraningList);
                }else {
                    fxjcModelTraning.setXlDate(new Date());
                    modelTraningListService.updateById(fxjcModelTraning);
                }
                return BaseUtil.execPyScript(new PyVo("城投债",2,"ctz_basic_model"));
            }
        }
        if (type == 2) {
            if (checkTraning("cyz_best_model")){
                System.out.println("拥有bestmodel");
				checkTraningBefore(type);
                FxjcModelTraningList fxjcModelTraningList = new FxjcModelTraningList();
                fxjcModelTraningList.setMoudleName("cyz_best_model");
                fxjcModelTraningList.setXlDate(new Date());
                fxjcModelTraningList.setType(type);
                modelTraningListService.save(fxjcModelTraningList);
                return BaseUtil.execPyScript(new PyVo("产业债",2,"cyz_best_model"));
            }else {
                System.out.println("未拥有bestmodel");
                FxjcModelTraningList fxjcModelTraning = checkTraningObj("cyz_basic_model");
                if (fxjcModelTraning == null) {
                    System.out.println("进入产业债方法---");
                    FxjcModelTraningList fxjcModelTraningList = new FxjcModelTraningList();
                    fxjcModelTraningList.setMoudleName("cyz_basic_model");
                    fxjcModelTraningList.setXlDate(new Date());
                    fxjcModelTraningList.setType(type);
                    modelTraningListService.save(fxjcModelTraningList);
                }else {
                    fxjcModelTraning.setXlDate(new Date());
                    modelTraningListService.updateById(fxjcModelTraning);
                }
                return BaseUtil.execPyScript(new PyVo("产业债",2,"cyz_best_model"));
            }
        }
        if (type == 3) {
            if (checkTraning("yh_best_model")){
				checkTraningBefore(type);
                FxjcModelTraningList fxjcModelTraningList = new FxjcModelTraningList();
                fxjcModelTraningList.setMoudleName("yh_best_model");
                fxjcModelTraningList.setXlDate(new Date());
                fxjcModelTraningList.setType(type);
                modelTraningListService.save(fxjcModelTraningList);
                return BaseUtil.execPyScript(new PyVo("银行债",2,"yh_best_model"));
            }else {
                FxjcModelTraningList fxjcModelTraning = checkTraningObj("yh_basic_model");
                if (fxjcModelTraning == null) {
                    FxjcModelTraningList fxjcModelTraningList = new FxjcModelTraningList();
                    fxjcModelTraningList.setMoudleName("yh_basic_model");
                    fxjcModelTraningList.setXlDate(new Date());
                    fxjcModelTraningList.setType(type);
                    modelTraningListService.save(fxjcModelTraningList);
                }else {
                    fxjcModelTraning.setXlDate(new Date());
                    modelTraningListService.updateById(fxjcModelTraning);
                }
                return BaseUtil.execPyScript(new PyVo("银行债",2,"yh_best_model"));
            }
        }
        if (type == 4) {
            if (checkTraning("bx_best_model")){
				checkTraningBefore(type);
                FxjcModelTraningList fxjcModelTraningList = new FxjcModelTraningList();
                fxjcModelTraningList.setMoudleName("bx_best_model");
                fxjcModelTraningList.setXlDate(new Date());
                fxjcModelTraningList.setType(type);
                modelTraningListService.save(fxjcModelTraningList);
                return BaseUtil.execPyScript(new PyVo("保险债",2,"bx_best_model"));
            }else {
                FxjcModelTraningList fxjcModelTraning = checkTraningObj("bx_basic_model");
                if (fxjcModelTraning == null) {
                    FxjcModelTraningList fxjcModelTraningList = new FxjcModelTraningList();
                    fxjcModelTraningList.setMoudleName("bx_basic_model");
                    fxjcModelTraningList.setXlDate(new Date());
                    fxjcModelTraningList.setType(type);
                    modelTraningListService.save(fxjcModelTraningList);
                }else {
                    fxjcModelTraning.setXlDate(new Date());
                    modelTraningListService.updateById(fxjcModelTraning);
                }
                return BaseUtil.execPyScript(new PyVo("保险债",2,"bx_best_model"));
            }
        }
        if (type == 5) {
            if (checkTraning("zq_best_model")){
				checkTraningBefore(type);
                FxjcModelTraningList fxjcModelTraningList = new FxjcModelTraningList();
                fxjcModelTraningList.setMoudleName("zq_best_model");
                fxjcModelTraningList.setXlDate(new Date());
                fxjcModelTraningList.setType(type);
                modelTraningListService.save(fxjcModelTraningList);
                return BaseUtil.execPyScript(new PyVo("证券债",2,"zq_best_model"));
            }else {
                FxjcModelTraningList fxjcModelTraning = checkTraningObj("zq_basic_model");
                if (fxjcModelTraning == null) {
                    FxjcModelTraningList fxjcModelTraningList = new FxjcModelTraningList();
                    fxjcModelTraningList.setMoudleName("zq_basic_model");
                    fxjcModelTraningList.setXlDate(new Date());
                    fxjcModelTraningList.setType(type);
                    modelTraningListService.save(fxjcModelTraningList);
                }else {
                    fxjcModelTraning.setXlDate(new Date());
                    modelTraningListService.updateById(fxjcModelTraning);
                }
                return BaseUtil.execPyScript(new PyVo("证券债",2,"zq_best_model"));
            }
        }
        return Result.fail("模型训练失败，请重新尝试！");
    }

    private boolean checkTraning(String modelName){
        QueryWrapper<FxjcModelTraningList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("moudle_name",modelName);
        List<FxjcModelTraningList> traningLists = modelTraningListService.list(queryWrapper);
        return CollectionUtil.isEmpty(traningLists) ? true:false;
    }


    private void checkTraningBefore(Integer type){
        QueryWrapper<FxjcQuota> queryWrapper = new QueryWrapper<>();
        FxjcQuota fxjcQuota = new FxjcQuota();
        fxjcQuota.setType(type);
        fxjcQuota.setStatus(1);
        queryWrapper.setEntity(fxjcQuota);
        List<FxjcQuota> list = fxjcQuotaService.list(queryWrapper);
        if (list != null && list.size() >0) {
            throw new BusinessException("最优模型不存在，请勾选全部指标！");
        }
    }


    private FxjcModelTraningList checkTraningObj(String modelName){
        QueryWrapper<FxjcModelTraningList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("moudle_name",modelName);
        return modelTraningListService.getOne(queryWrapper);
    }





    @GetMapping(value = "training-assessment")
    public Result trainAssessment(@RequestParam(name = "type", required = false) Integer type,
                                  @RequestParam(name = "pageSize", defaultValue = "10", required = false) Integer pageSize,
                                  @RequestParam(name = "pageNo", defaultValue = "1", required = false) Integer pageNo,
                                  @RequestParam(name = "zwzt", required = false) String zwzt){
        QueryWrapper<FxjcModelTraningList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type",type);
        queryWrapper.orderByDesc("xl_date").last("limit 1");
        FxjcModelTraningList fxjcModelTraningList = modelTraningListService.getOne(queryWrapper);

        String flag="0";

        if (fxjcModelTraningList != null){
            if(fxjcModelTraningList.getMoudleName().contains("best")){
            	flag = "1";
			}
        }

        String tableName = "";
        switch (type) {
            case 1: tableName ="fxjc_ctz_traning_result"; break;
            case 2: tableName ="fxjc_cyz_traning_result"; break;
            case 3: tableName ="fxjc_yh_traning_result"; break;
            case 4: tableName ="fxjc_bx_traning_result"; break;
            case 5: tableName ="fxjc_zq_traning_result"; break;
        }

        List<Map<String,Object>> tableData =  fxjcCyzMapper.selectByTable(tableName);


        Map<String,Object> map = new HashMap<>();
        map.put("pageSize", pageSize);
        map.put("pageNo",(pageNo-1)*pageSize);
        map.put("tableName",tableName);
        Page page = new Page(pageNo,pageSize);
        IPage dataList =  fxjcCyzMapper.selectTrainingDataByTable(page,tableName,zwzt);

        Map<String, Object> params = new HashMap<>();
        params.put("flag",flag);
        params.put("tableData",tableData);
        params.put("dataList",dataList);
        return Result.succ(params);
    }





}
